{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:13.605161Z",
     "start_time": "2021-02-18T02:27:10.210987Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "plt.style.use('fivethirtyeight')\n",
    "\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\n",
    "from tensorflow.keras.losses import binary_crossentropy\n",
    "from tensorflow.keras.optimizers import Adam\n",
    "from tensorflow.keras.metrics import AUC\n",
    "from NFM import NFM\n",
    "\n",
    "from sklearn.metrics import roc_auc_score\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:15.450929Z",
     "start_time": "2021-02-18T02:27:15.436966Z"
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"数据准备\"\"\"\n",
    "file_path = './preprocessed_data/'\n",
    "def prepared_data(file_path):\n",
    "    # 读入训练集， 验证集和测试集\n",
    "    train = pd.read_csv(file_path + 'train_set.csv')\n",
    "    val = pd.read_csv(file_path + 'val_set.csv')\n",
    "    test = pd.read_csv(file_path + 'test_set.csv')\n",
    "    \n",
    "    sparse_feas = [col for col in train.columns if col[0] == 'C']\n",
    "    dense_feas = [col for col in train.columns if col[0] == 'I']\n",
    "    \n",
    "    trn_x, trn_y = [train[dense_feas].values, train[sparse_feas].values], train['Label'].values\n",
    "    val_x, val_y = [val[dense_feas].values, val[sparse_feas].values], val['Label'].values\n",
    "    test_x = [test[dense_feas].values, test[sparse_feas].values]\n",
    "    \n",
    "    fea_info = np.load(file_path + 'fea_info.npy', allow_pickle=True)\n",
    "    \n",
    "    return fea_info, (trn_x, trn_y), (val_x, val_y), test_x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:16.301007Z",
     "start_time": "2021-02-18T02:27:16.268740Z"
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"导入数据\"\"\"\n",
    "fea_cols, (trn_x, trn_y), (val_x, val_y), test_x = prepared_data(file_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:21.156710Z",
     "start_time": "2021-02-18T02:27:21.147689Z"
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"设置超参数\"\"\"\n",
    "embed_dim = 8\n",
    "dnn_dropout = 0.5\n",
    "hidden_units = [256, 128, 64]\n",
    "\n",
    "learning_rate = 0.001\n",
    "batch_size = 64\n",
    "epochs = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:22.913964Z",
     "start_time": "2021-02-18T02:27:22.460178Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"model\"\n",
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "input_2 (InputLayer)            [(None, 26)]         0                                            \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem (Slici (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_1 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_2 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_3 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_4 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_5 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_6 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_7 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_8 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_9 (Sli (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_10 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_11 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_12 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_13 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_14 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_15 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_16 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_17 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_18 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_19 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_20 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_21 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_22 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_23 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_24 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "tf.__operators__.getitem_25 (Sl (None,)              0           input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "embedding (Embedding)           (None, 8)            632         tf.__operators__.getitem[0][0]   \n",
      "__________________________________________________________________________________________________\n",
      "embedding_1 (Embedding)         (None, 8)            2016        tf.__operators__.getitem_1[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_2 (Embedding)         (None, 8)            10344       tf.__operators__.getitem_2[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_3 (Embedding)         (None, 8)            8344        tf.__operators__.getitem_3[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_4 (Embedding)         (None, 8)            240         tf.__operators__.getitem_4[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_5 (Embedding)         (None, 8)            56          tf.__operators__.getitem_5[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_6 (Embedding)         (None, 8)            9312        tf.__operators__.getitem_6[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_7 (Embedding)         (None, 8)            312         tf.__operators__.getitem_7[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_8 (Embedding)         (None, 8)            16          tf.__operators__.getitem_8[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_9 (Embedding)         (None, 8)            7264        tf.__operators__.getitem_9[0][0] \n",
      "__________________________________________________________________________________________________\n",
      "embedding_10 (Embedding)        (None, 8)            7408        tf.__operators__.getitem_10[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_11 (Embedding)        (None, 8)            9912        tf.__operators__.getitem_11[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_12 (Embedding)        (None, 8)            6592        tf.__operators__.getitem_12[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_13 (Embedding)        (None, 8)            160         tf.__operators__.getitem_13[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_14 (Embedding)        (None, 8)            6552        tf.__operators__.getitem_14[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_15 (Embedding)        (None, 8)            9272        tf.__operators__.getitem_15[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_16 (Embedding)        (None, 8)            72          tf.__operators__.getitem_16[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_17 (Embedding)        (None, 8)            4272        tf.__operators__.getitem_17[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_18 (Embedding)        (None, 8)            1608        tf.__operators__.getitem_18[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_19 (Embedding)        (None, 8)            32          tf.__operators__.getitem_19[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_20 (Embedding)        (None, 8)            9632        tf.__operators__.getitem_20[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_21 (Embedding)        (None, 8)            56          tf.__operators__.getitem_21[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_22 (Embedding)        (None, 8)            96          tf.__operators__.getitem_22[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_23 (Embedding)        (None, 8)            5832        tf.__operators__.getitem_23[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_24 (Embedding)        (None, 8)            264         tf.__operators__.getitem_24[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "embedding_25 (Embedding)        (None, 8)            4432        tf.__operators__.getitem_25[0][0]\n",
      "__________________________________________________________________________________________________\n",
      "tf.convert_to_tensor (TFOpLambd (26, None, 8)        0           embedding[0][0]                  \n",
      "                                                                 embedding_1[0][0]                \n",
      "                                                                 embedding_2[0][0]                \n",
      "                                                                 embedding_3[0][0]                \n",
      "                                                                 embedding_4[0][0]                \n",
      "                                                                 embedding_5[0][0]                \n",
      "                                                                 embedding_6[0][0]                \n",
      "                                                                 embedding_7[0][0]                \n",
      "                                                                 embedding_8[0][0]                \n",
      "                                                                 embedding_9[0][0]                \n",
      "                                                                 embedding_10[0][0]               \n",
      "                                                                 embedding_11[0][0]               \n",
      "                                                                 embedding_12[0][0]               \n",
      "                                                                 embedding_13[0][0]               \n",
      "                                                                 embedding_14[0][0]               \n",
      "                                                                 embedding_15[0][0]               \n",
      "                                                                 embedding_16[0][0]               \n",
      "                                                                 embedding_17[0][0]               \n",
      "                                                                 embedding_18[0][0]               \n",
      "                                                                 embedding_19[0][0]               \n",
      "                                                                 embedding_20[0][0]               \n",
      "                                                                 embedding_21[0][0]               \n",
      "                                                                 embedding_22[0][0]               \n",
      "                                                                 embedding_23[0][0]               \n",
      "                                                                 embedding_24[0][0]               \n",
      "                                                                 embedding_25[0][0]               \n",
      "__________________________________________________________________________________________________\n",
      "tf.compat.v1.transpose (TFOpLam (None, 26, 8)        0           tf.convert_to_tensor[0][0]       \n",
      "__________________________________________________________________________________________________\n",
      "input_1 (InputLayer)            [(None, 13)]         0                                            \n",
      "__________________________________________________________________________________________________\n",
      "bi_interaction_pooling (BiInter (None, 8)            0           tf.compat.v1.transpose[0][0]     \n",
      "__________________________________________________________________________________________________\n",
      "tf.concat (TFOpLambda)          (None, 21)           0           input_1[0][0]                    \n",
      "                                                                 bi_interaction_pooling[0][0]     \n",
      "__________________________________________________________________________________________________\n",
      "batch_normalization (BatchNorma (None, 21)           84          tf.concat[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "dnn (DNN)                       (None, 64)           46784       batch_normalization[0][0]        \n",
      "__________________________________________________________________________________________________\n",
      "dense_3 (Dense)                 (None, 1)            65          dnn[0][0]                        \n",
      "__________________________________________________________________________________________________\n",
      "tf.math.sigmoid (TFOpLambda)    (None, 1)            0           dense_3[0][0]                    \n",
      "==================================================================================================\n",
      "Total params: 151,661\n",
      "Trainable params: 151,619\n",
      "Non-trainable params: 42\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "\"\"\"模型建立\"\"\"\n",
    "model = NFM(fea_cols, hidden_units, dnn_dropout=dnn_dropout)\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:24.492743Z",
     "start_time": "2021-02-18T02:27:24.466846Z"
    }
   },
   "outputs": [],
   "source": [
    "\"\"\"模型编译\"\"\"\n",
    "model.compile(loss=binary_crossentropy, optimizer=Adam(learning_rate=learning_rate),\n",
    "                      metrics=[AUC()])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:30.234691Z",
     "start_time": "2021-02-18T02:27:26.797576Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/50\n",
      "18/18 [==============================] - 3s 49ms/step - loss: 0.6044 - auc: 0.4751 - val_loss: 0.5115 - val_auc: 0.6672\n",
      "Epoch 2/50\n",
      "18/18 [==============================] - 0s 4ms/step - loss: 0.4933 - auc: 0.7027 - val_loss: 0.5011 - val_auc: 0.6904\n",
      "Epoch 3/50\n",
      "18/18 [==============================] - 0s 4ms/step - loss: 0.4324 - auc: 0.8069 - val_loss: 0.5169 - val_auc: 0.6830\n",
      "Epoch 4/50\n",
      "18/18 [==============================] - 0s 5ms/step - loss: 0.2863 - auc: 0.9517 - val_loss: 0.6582 - val_auc: 0.6425\n",
      "Epoch 5/50\n",
      "18/18 [==============================] - 0s 4ms/step - loss: 0.1115 - auc: 0.9925 - val_loss: 0.8803 - val_auc: 0.6580\n",
      "\n",
      "Epoch 00005: ReduceLROnPlateau reducing learning rate to 1.0000000474974514e-05.\n",
      "Epoch 6/50\n",
      "18/18 [==============================] - 0s 4ms/step - loss: 0.0462 - auc: 0.9990 - val_loss: 0.8829 - val_auc: 0.6564\n",
      "Epoch 7/50\n",
      "18/18 [==============================] - 0s 5ms/step - loss: 0.0425 - auc: 0.9996 - val_loss: 0.8860 - val_auc: 0.6581\n"
     ]
    }
   ],
   "source": [
    "\"\"\"模型训练\"\"\"\n",
    "callbacks = [\n",
    "    EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True),   # 早停\n",
    "    ReduceLROnPlateau(monitor='val_loss', patience=3, factor=0.01, verbose=1)\n",
    "]\n",
    "\n",
    "history = model.fit(\n",
    "                    trn_x,\n",
    "                    trn_y,\n",
    "                    epochs=epochs,\n",
    "                    callbacks=callbacks,  # checkpoint\n",
    "                    batch_size=batch_size,\n",
    "                    validation_split=0.1\n",
    "                    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:42.783128Z",
     "start_time": "2021-02-18T02:27:42.638201Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"可视化下看看训练情况\"\"\"\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('Model loss')\n",
    "plt.ylabel('Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(['Train', 'Test'], loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个目前需要加数据， 训练效果不是太好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-02-18T02:27:58.556652Z",
     "start_time": "2021-02-18T02:27:58.508782Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5/5 [==============================] - 0s 1ms/step - loss: 0.4253 - auc: 0.6903\n",
      "test AUC: 0.690305\n"
     ]
    }
   ],
   "source": [
    "\"\"\"模型评估\"\"\"\n",
    "print('test AUC: %f' % model.evaluate(val_x, val_y, batch_size=batch_size)[1])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
